﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Mrc.Common;
using Mrc.Common.Enum;
using System;

namespace Mrc.Application.Filter
{
    public class HttpGlobalExceptionFilter : IExceptionFilter
    {
        public HttpGlobalExceptionFilter()
        {
        }

        protected JsonResult JsonFailedMsg(string msg = null)
        {
            return new JsonResult(new AjaxResult(ResultStatus.Failed, msg));
        }

        public void OnException(ExceptionContext filterContext)
        {
            if (filterContext.ExceptionHandled)
                return;

            //执行过程出现未处理异常
            Exception ex = filterContext.Exception;
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                string msg = null;
                if (ex is InvalidInputException || ex is MrcException)
                {
                    msg = ex.Message;
                }
                else
                {
                    this.LogException(filterContext);
                    msg = "服务器错误";
                }
                filterContext.Result = this.JsonFailedMsg(msg);
                filterContext.ExceptionHandled = false;
                return;
            }
            else
            {
                //对于非 ajax 请求
                this.LogException(filterContext);
                return;
            }
        }

        /// <summary>
        ///  将错误记录进日志
        /// </summary>
        /// <param name="filterContext"></param>
        private void LogException(ExceptionContext filterContext)
        {
            ILoggerFactory loggerFactory = filterContext.HttpContext.RequestServices.GetService(typeof(ILoggerFactory)) as ILoggerFactory;
            ILogger logger = loggerFactory.CreateLogger(filterContext.ActionDescriptor.DisplayName);
            logger.LogError("Error: {0}, {1}", ReplaceParticular(filterContext.Exception.Message), ReplaceParticular(filterContext.Exception.StackTrace));
        }

        private static string ReplaceParticular(string s)
        {
            if (string.IsNullOrEmpty(s))
                return s;

            return s.Replace("\r", "#R#").Replace("\n", "#N#").Replace("|", "#VERTICAL#");
        }
    }
}